home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #2 / Monster Media No. 2 (Monster Media)(1994).ISO / prog_gen / xv_pc16a.zip / ROTOR.PAS < prev    next >
Pascal/Delphi Source File  |  1994-04-20  |  6KB  |  227 lines

  1. PROGRAM Rotor;
  2. {
  3. This program demonstrates how to define a new object in the XView-PC
  4. interface unsing the "callbacks" of a "canvas".
  5. Demonstrated is also how to use several "canvas" objects in the same window,
  6. the use of "accelerator keys", and a "trick" to drive an object simulating
  7. events.
  8.  
  9. By Antonio Carlos Moreirao de Queiroz - acmq@coe.ufrj.br
  10. Version 1.0 - 17/04/94
  11.  
  12. A rotary button object is created using the "callbacks" of a "canvas".
  13. The angle is kept in "client_data", by a type cast.
  14. Does not work in black and white modes.
  15. }
  16.  
  17. USES Mickey,XView,Graph;
  18.  
  19. {The "interposer" for "accelerator keys"}
  20.  
  21. {$I hotkeys.inc}
  22.  
  23. {Rotor parameters}
  24.  
  25. CONST
  26.   rmajor=35;
  27.   rminor=rmajor div 2;
  28.   centerx=rmajor;
  29.   centery=rmajor+9;
  30.   rbase=rminor+3;
  31.   rpoint=rmajor-3;
  32.   ht=rpoint-rbase;
  33.   ht2=ht div 2;
  34.   range=180;
  35.  
  36. {Graphics board and mode}
  37.   board=0;
  38.   mode=0;
  39.  
  40. VAR
  41.   frame1,canvas1,canvas2,canvas3,canvas4,tty1:Xv_opaque;
  42.  
  43. {Auxiliary functions}
  44.  
  45. FUNCTION Si(x:INTEGER):STRING; {Integer to string converter}
  46. VAR
  47.   t:STRING;
  48. BEGIN
  49.   Str(x,t);
  50.   Si:=t
  51. END;
  52.  
  53. FUNCTION Angle(x,y:INTEGER):INTEGER; {Full circle ArcTan function}
  54. VAR
  55.   t:REAL;
  56. BEGIN
  57.   IF x=0 THEN BEGIN
  58.     IF y>0 THEN Angle:=range div 2 ELSE Angle:=-range div 2
  59.   END
  60.   ELSE BEGIN
  61.     t:=ArcTan(y/x);
  62.     IF x<0 THEN IF y>0 THEN t:=t+Pi ELSE t:=t-Pi;
  63.     Angle:=Round(range/Pi*t)
  64.   END
  65. END;
  66.  
  67. PROCEDURE Triangle(angle:INTEGER); {Draws the rotor arrow}
  68. VAR
  69.   t:ARRAY[1..3] of RECORD x,y:INTEGER END;
  70.   alpha,gamma,asp:REAL;
  71.   xasp,yasp:WORD;
  72. BEGIN
  73.   GetAspectRatio(xasp,yasp);
  74.   asp:=xasp/yasp;
  75.   alpha:=angle*Pi/range;
  76.   gamma:=Pi/2-alpha;
  77.   SetFillStyle(SolidFill,GetColor);
  78.   t[1].x:=centerx+Round(rbase*cos(alpha)+ht2*cos(gamma));
  79.   t[1].y:=centery-Round(asp*(rbase*sin(alpha)-ht2*sin(gamma)));
  80.   t[2].x:=centerx+Round(rbase*cos(alpha)-ht2*cos(gamma));
  81.   t[2].y:=centery-Round(asp*(rbase*sin(alpha)+ht2*sin(gamma)));
  82.   t[3].x:=centerx+Round((rbase+ht)*cos(alpha));
  83.   t[3].y:=centery-Round(asp*((rbase+ht)*sin(alpha)));
  84.   FillPoly(3,t);
  85. END;
  86.  
  87. {$F+}
  88.  
  89. {Callback procedures}
  90.  
  91. PROCEDURE DrawRotor(obj:Xv_opaque); {Notify handler for rotors}
  92. BEGIN
  93.   SetColor(c_shadow);
  94.   Circle(centerx,centery,rmajor);
  95.   Circle(centerx,centery,rminor);
  96.   SetFillStyle(SolidFill,c_active);
  97.   FloodFill(centerx+rmajor-1,centery,c_shadow);
  98.   SetColor(c_light);
  99.   Arc(centerx,centery,45,225,rminor);
  100.   Arc(centerx,centery,225,45,rmajor);
  101.   SetColor(c_white);
  102.   Triangle(INTEGER(obj^.client_data));
  103.   SetColor(c_black);
  104.   OutTextXY(0,0,Si(INTEGER(obj^.client_data)));
  105.   SetTextJustify(CenterText,BottomText);
  106.   OutTextXY(centerx,obj^.dy-1,obj^.xv_label);
  107. END;
  108.  
  109. PROCEDURE EventsRotor(obj:Xv_opaque); {Event handler for rotors}
  110. VAR
  111.   x1,y1:INTEGER;
  112. BEGIN
  113.   IF (ie_code=MS_LEFT) or (ie_code=LOC_DRAG) THEN BEGIN
  114.     {Sets the viewport, since there is more than one canvas in the window}
  115.     x1:=active_w^.x+obj^.x+mrgx+1;
  116.     y1:=active_w^.y+obj^.y+mrgy+1;
  117.     SetViewPort(x1,y1,x1+obj^.dx-2,y1+obj^.dy-2,ClipOn);
  118.     SetColor(c_active);
  119.     Triangle(INTEGER(obj^.client_data));
  120.     INTEGER(obj^.client_data):=Angle(ie_locx-centerx,centery-ie_locy);
  121.     SetColor(c_white);
  122.     Triangle(INTEGER(obj^.client_data));
  123.     SetFillStyle(SolidFill,c_normal);
  124.     Bar(0,0,38,6);
  125.     SetColor(c_black);
  126.     OutTextXY(0,0,Si(INTEGER(obj^.client_data)));
  127.   END
  128. END;
  129.  
  130. PROCEDURE State(obj:Xv_opaque); {Reads the rotors}
  131. BEGIN
  132.   ttysw_output(tty1,'Status:'^M^J);
  133.   ttysw_output(tty1,canvas1^.xv_label+': '+Si(INTEGER(canvas1^.client_data))+^M^J);
  134.   ttysw_output(tty1,canvas2^.xv_label+': '+Si(INTEGER(canvas2^.client_data))+^M^J);
  135.   ttysw_output(tty1,canvas3^.xv_label+': '+Si(INTEGER(canvas3^.client_data))+^M^J);
  136.   ttysw_output(tty1,canvas4^.xv_label+': '+Si(INTEGER(canvas4^.client_data))+^M^J);
  137. END;
  138.  
  139. PROCEDURE Rotate(obj:Xv_opaque); {Moves the rotors simulating events}
  140. VAR
  141.   angle:INTEGER;
  142.   t:REAL;
  143. BEGIN
  144.   angle:=0;
  145.   ttysw_output(tty1,'Rotating...(touch a key to stop)'^M^J);
  146.   REPEAT
  147.     t:=Pi/range*angle;
  148.     {ie_code is already MS_LEFT}
  149.     ie_locx:=Round(centerx+rmajor*Cos(t));
  150.     ie_locy:=Round(centery+rmajor*Sin(t));
  151.     EventsRotor(canvas1);
  152.     EventsRotor(canvas2);
  153.     EventsRotor(canvas3);
  154.     EventsRotor(canvas4);
  155.     Inc(angle,10);
  156.     IF angle>range THEN angle:=10-range
  157.   UNTIL mkbhit
  158. END;
  159.  
  160. PROCEDURE Quit(obj:Xv_opaque);
  161. BEGIN
  162.   xv_end:=TRUE
  163. END;
  164.  
  165. {$F-}
  166.  
  167. {Creation routine for the rotor}
  168.  
  169. FUNCTION xv_create_rotor(name:xv_label_type; xx,yy,angle:INTEGER):Xv_opaque;
  170. VAR
  171.   rotor:Xv_opaque;
  172. BEGIN
  173.   rotor:=xv_create(canvas);
  174.   WITH rotor^ DO BEGIN
  175.     xv_label:=name;
  176.     back_color:=c_normal; fore_color:=c_normal;
  177.     x:=xx; y:=yy;
  178.     can_xext:=FALSE; dx:=2*centerx+2;
  179.     can_yext:=FALSE; dy:=2*centery+2;
  180.     notify_handler:=DrawRotor;
  181.     event_handler:=EventsRotor;
  182.     INTEGER(client_data):=angle;
  183.   END;
  184.   xv_create_rotor:=rotor
  185. END;
  186.  
  187. BEGIN
  188.   xv_init(board,mode);
  189.   {The objects are adjusted to the size of the rotors}
  190.   frame1:=xv_create(frame);
  191.   WITH frame1^ DO BEGIN
  192.     xv_label:='Rotor';
  193.     dy:=319;
  194.     dymin:=319;
  195.   END;
  196.   canvas1:=xv_create_rotor('Rotor 1',0,0,45);
  197.   canvas2:=xv_create_rotor('Rotor 2',canvas1^.x+canvas1^.dx+5,0,-45);
  198.   canvas3:=xv_create_rotor('Rotor 3',canvas2^.x+canvas1^.dx+5,0,-180);
  199.   canvas4:=xv_create_rotor('Rotor 4',canvas3^.x+canvas1^.dx+5,0,-180);
  200.   {Never referenced buttons can be created without declaration}
  201.   WITH xv_create(button)^ DO BEGIN
  202.     xv_label:='State';
  203.     y:=canvas1^.dy+3;
  204.     notify_handler:=State;
  205.   END;
  206.   WITH xv_create(button)^ DO BEGIN
  207.     xv_label:='rOtate';
  208.     y:=canvas1^.dy+3; x:=50;
  209.     notify_handler:=Rotate;
  210.   END;
  211.   WITH xv_create(button)^ DO BEGIN
  212.     xv_label:='Quit';
  213.     y:=canvas1^.dy+3; x:=109;
  214.     notify_handler:=Quit;
  215.   END;
  216.   frame1^.dx:=canvas4^.x+canvas4^.dx+2*mrgx;
  217.   frame1^.x:=(GetMaxX-frame1^.dx) div 2;
  218.   frame1^.y:=(GetMaxY-frame1^.dy) div 2;
  219.   tty1:=xv_create(tty);
  220.   tty1^.y:=canvas1^.dy+18;
  221.   ttysw_output(tty1,'Demonstration of the rotor object'^M^J);
  222.   {"Interposer" installation}
  223.   interposer:=HotKeys;
  224.   xv_main_loop(frame1);
  225.   RestoreCrtMode;
  226. END.
  227.